package br.edu.ufcg.lsd.wbis;

import java.lang.reflect.Proxy;

import br.edu.ufcg.lsd.wbis.control.WBISController;
import br.edu.ufcg.lsd.wbis.control.WBISFacade;
import br.edu.ufcg.lsd.wbis.control.exception.AuthenticationFailedException;
import br.edu.ufcg.lsd.wbis.control.exception.BusinessValidationException;
import br.edu.ufcg.lsd.wbis.control.exception.CannotOpenDatabaseSessionException;
import br.edu.ufcg.lsd.wbis.control.exception.DuplicatedIdentifierException;
import br.edu.ufcg.lsd.wbis.control.exception.PermissionDeniedException;
import br.edu.ufcg.lsd.wbis.control.exception.RootUserAlreadyCreatedException;
import br.edu.ufcg.lsd.wbis.control.exception.RootUserCreationCancelledException;
import br.edu.ufcg.lsd.wbis.control.exception.UnknownEntityException;
import br.edu.ufcg.lsd.wbis.control.exception.UserNotAuthorizedException;
import br.edu.ufcg.lsd.wbis.control.user.UserLevel;
import br.edu.ufcg.lsd.wbis.control.user.UserMatcher;
import br.edu.ufcg.lsd.wbis.control.util.HibernateUtil;


//FIXME CONSERTAR ESSA CLASSE DEPOIS QUE METODOS DA FACHADA FORAM MODIFICADOS

/**
 * Facade needed for access by the acceptance tests run through EasyAccept
 * library.
 * 
 * @author Renato Miceli
 * 
 */
public class WBISEAFacade {

	private WBISFacade controller;

	public WBISEAFacade() throws CannotOpenDatabaseSessionException {
		rebuild();
	}

	public void rebuild() throws CannotOpenDatabaseSessionException {
		HibernateUtil.getInstance(HibernateUtil.getTestingConfigFilePath());
		this.controller = (WBISFacade) Proxy.newProxyInstance(
				WBISController.class.getClassLoader(), WBISController.class
						.getInterfaces(), new ErrorInvocationHandler());
	}

	public void addUser(String login, String pswd, String name, String email,
			String strLevel) throws BusinessValidationException,
			DuplicatedIdentifierException {

		this.controller.addCommonUser(login, pswd, name, email);
	}

	public void addAdminUser(String myLogin, String myPass, String login,
			String pswd, String name, String email)
			throws BusinessValidationException, DuplicatedIdentifierException,
			RootUserCreationCancelledException,
			RootUserAlreadyCreatedException, PermissionDeniedException,
			AuthenticationFailedException, UserNotAuthorizedException {

		//FIXME this.controller.addAdminUser(myLogin, myPass, login, pswd, name, email);
	}

	public void addRootUser(String login, String pswd, String name, String email)
			throws BusinessValidationException, DuplicatedIdentifierException,
			RootUserCreationCancelledException, RootUserAlreadyCreatedException {

		this.controller.addRootUser(login, pswd, name, email);
	}

	private UserLevel getLevelByString(String strLevel) {
		if (strLevel.equalsIgnoreCase("admin")) {
			return UserLevel.ADMIN;
		} else {
			return UserLevel.COMMON_USER;
		}
	}

	public String getUserName(String myLogin, String myPass, String login)
			throws BusinessValidationException, UnknownEntityException,
			PermissionDeniedException, AuthenticationFailedException,
			UserNotAuthorizedException {
		return this.controller.getUser(myLogin, myPass, login).getName();
	}

	public String getUserEmail(String myLogin, String myPass, String login)
			throws BusinessValidationException, UnknownEntityException,
			PermissionDeniedException, AuthenticationFailedException,
			UserNotAuthorizedException {
		return this.controller.getUser(myLogin, myPass, login).getEmail();
	}

	public void updateUserInfo(String requesterLogin, String requesterPswd,
			String login, String newName, String newEmail, String strLevel,
			boolean authorized) throws BusinessValidationException,
			UnknownEntityException, AuthenticationFailedException,
			UserNotAuthorizedException, PermissionDeniedException {

		UserLevel level = getLevelByString(strLevel);
		this.controller.updateUserInfo(requesterLogin, requesterPswd, login,
				newName, newEmail, level, authorized);
	}

	public void updateUserPassword(String requesterLogin, String requesterPswd,
			String login, String newPassword)
			throws BusinessValidationException, UnknownEntityException,
			AuthenticationFailedException, UserNotAuthorizedException,
			PermissionDeniedException {

		this.controller.updateUserPassword(requesterLogin, requesterPswd,
				login, newPassword);
	}

	public int getNumberOfUsers(String myLogin, String myPass)
			throws BusinessValidationException, AuthenticationFailedException,
			UserNotAuthorizedException, PermissionDeniedException {
		return this.controller.getUsers(myLogin, myPass).size();
	}

	public void removeUser(String requesterLogin, String requesterPswd,
			String loginToRemove) throws BusinessValidationException,
			UnknownEntityException, AuthenticationFailedException,
			UserNotAuthorizedException, PermissionDeniedException {
		this.controller
				.removeUser(requesterLogin, requesterPswd, loginToRemove);
	}

	public boolean isUserAuthorized(String myLogin, String myPass, String login)
			throws UnknownEntityException, BusinessValidationException,
			PermissionDeniedException, AuthenticationFailedException,
			UserNotAuthorizedException {
		return this.controller.getUser(myLogin, myPass, login).isAuthorized();
	}

	public void authenticateUser(String login, String password)
			throws BusinessValidationException, AuthenticationFailedException,
			UserNotAuthorizedException {
		this.controller.authenticateUser(login, password);
	}

	/*
	 * userMatcher.setAuthorized(authorized); userMatcher.setEmail(email);
	 * userMatcher.setEmailSearchType(emailType); userMatcher.setLogin(login);
	 * userMatcher.setLoginSearchType(loginType); userMatcher.setName(name);
	 * userMatcher.setNameSearchType(nameType); userMatcher.setUserLevel(level);
	 */

	public void searchUsers(String userLogin, String password, String name,
			String nameMatcherType, String login, String loginMatcherType,
			String email, String emailMatcherType, String userAuthorization,
			String userLevel) throws BusinessValidationException,
			AuthenticationFailedException, UserNotAuthorizedException,
			PermissionDeniedException {

		UserMatcher userMatcher = new UserMatcher();

		if (!name.equals("") && name != null) {
			userMatcher.setName(name);
		}
		if (!login.equals("") && login != null) {
			userMatcher.setLogin(login);
		}
		if (!email.equals("") && email != null) {
			userMatcher.setEmail(email);
		}

//		if (nameMatcherType.equalsIgnoreCase("default")
//				&& nameMatcherType != null) {
//			userMatcher.setNameSearchType(StringMatchingType.DEFAULT);
//		}
//
//		if (loginMatcherType.equalsIgnoreCase("default")
//				&& loginMatcherType != null) {
//			userMatcher.setLoginSearchType(StringMatchingType.DEFAULT);
//		}
//
//		if (emailMatcherType.equalsIgnoreCase("default")
//				&& emailMatcherType != null) {
//			userMatcher.setEmailSearchType(StringMatchingType.DEFAULT);
//		}

		if (userAuthorization.equalsIgnoreCase("true")
				&& userAuthorization != null)
			userMatcher.setAuthorized(true);
		else if (userAuthorization.equalsIgnoreCase("false")
				&& userAuthorization != null)
			userMatcher.setAuthorized(false);

		if (userLevel.equalsIgnoreCase("admin") && userLevel != null)
			userMatcher.setUserLevel(UserLevel.ADMIN);
		if (userLevel.equalsIgnoreCase("common_user") && userLevel != null)
			userMatcher.setUserLevel(UserLevel.COMMON_USER);

		this.controller.searchUsers(userLogin, password, userMatcher);
	}

}
